#include <butil/logging.h>
#include <brpc/server.h>
#include "main.pb.h"

/*
    类与接口说明：
    一、日志类(brpc中自带日志，我们关闭它的日志采用自己的日志)
        #include <butil/logging.h>
        bool InitLogging(const LoggingSettings& settings)

    二、proto相关类
    1、RpcController 上下文管理类，主要用于判断rpc请求是否ok
    2、Closure 客户端和服务的用法不同
        客户端：主要用于设置异步处理回调，因为客户请求之后，并不清楚什么时候能够得到响应，可以设置回调方法当收到响应时，自动调用回调
        服务器：服务端请求处理完毕之后需要调用类中的Run接口宣告请求处理完毕
        NewCallback全局函数可以生成Closure对象，类似make_pair

    三、服务端相关类
    1、server 服务器类 ServerOptions 服务器参数类
    2、ClosureGuard Closure智能管理类

    四、客户端相关类
    1、Channel 信道类，客户端和服务器通信的信道，不是以套接字为单位，比套接字更细粒度
    2、ChannelOptions 信道参数配置类

    五：命名空间介绍
    主要三种命名空间：
    1、google::protobuf 涉及类：Closure、RpcController（抽象类）
    2、brpc 涉及类：Server、ServerOptions、Channel、ChannelOptions、Controller（继承RpcController类）、ClosureGuard
    3、ns_brpc 涉及类：main.pb.h中的所有类，EchoServer、EchoServer_Stub
*/

// 1、继承EchoServer类实现虚方法echo
class EchoServerImpl : public ns_brpc::EchoServer
{
public:
    void echo(google::protobuf::RpcController *controller,
              const ns_brpc::EchoRequest *request,
              ns_brpc::EchoResponse *response,
              google::protobuf::Closure *done)
    {
        // 处理请求
        std::cout << "[MESSAGE]:" << request->message();

        // 定义回显信息，设置响应
        std::string echo_msg = "echo->" + request->message();
        response->set_message(echo_msg);

        // 调用run宣告处理完毕
        // done->Run();
        brpc::ClosureGuard closure_gurad(done); // 智能管理
    }
};

int main()
{
    // 关闭自带日志
    logging::LoggingSettings settings;                                // 日志参数
    settings.logging_dest = logging::LoggingDestination::LOG_TO_NONE; // 设置参数取消日志
    logging::InitLogging(settings);                                   // 初始化日志

    // 2、创建服务器对象
    brpc::Server server;

    // 3、将echo服务加入服务器对象
    EchoServerImpl echo_server;
    int ret = server.AddService(&echo_server, brpc::ServiceOwnership::SERVER_DOESNT_OWN_SERVICE); // SERVER_DOESNT_OWN_SERVICE服务添加失败取消服务
    if (ret == -1)
    {
        std::cout << "服务添加失败\n";
        return -1;
    }

    // 4、启动服务器
    brpc::ServerOptions options;   // 定义服务器参数
    options.idle_timeout_sec = -1; // 无数据传输时，指定时间之后关闭连接，-1表示长连接
    options.num_threads = 1;       // io线程数量
    ret = server.Start(8080, &options);
    if (ret == -1)
    {
        std::cout << "启动服务器失败！\n";
        return -1;
    }

    // 服务器休眠直到 ctrl+c 按下，或者 stop 和 join 服务器
    server.RunUntilAskedToQuit();

    return 0;
}
